/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.awsmanager.utils;

import com.awsmanager.common.AWSCredential;
import com.awsmanager.common.EC2Region;
import com.awsmanager.common.S3StorageServer;
import com.awsmanager.common.SDBServer;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 *
 * @author Sean ODell
 */
public class ProcessXML {

    protected String errorMsg;
    protected HashMap xmlNodes;

    public ProcessXML(String xmlString, String nodeType) {
        NodeList nodeList = buildNodeList(xmlString, nodeType);
        xmlNodes = parseNodes(nodeList, nodeType);
    }

    /**
     * Get the value of errorMsg
     *
     * @return the value of errorMsg
     */
    public String getErrorMsg() {
        return errorMsg;
    }

    /**
     * Set the value of errorMsg
     *
     * @param errorMsg new value of errorMsg
     */
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    /**
     * Get the value of xmlNodes
     *
     * @return the value of xmlNodes
     */
    public HashMap getXmlNodes() {
        return xmlNodes;
    }

    /**
     * Set the value of xmlNodes
     *
     * @param xmlNodes new value of xmlNodes
     */
    public void setXmlNodes(HashMap xmlNodes) {
        this.xmlNodes = xmlNodes;
    }

    public NodeList buildNodeList(String xmlString, String nodeType) {

        NodeList nodeList = null;
        Document dom = null;
        DocumentBuilder db = null;

        ProcessText processXMLstring = new ProcessText();
        InputStream in = processXMLstring.strToInputStream(xmlString);
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        if (in != null) {
            try {
                db = dbf.newDocumentBuilder();
            } catch (ParserConfigurationException ex) {
                Logger.getLogger(ProcessXML.class.getName()).log(Level.SEVERE, null, ex);
            }
            if (db != null) {
                try {
                    dom = db.parse(in);
                } catch (SAXParseException ex) {
                    Logger.getLogger(ProcessXML.class.getName()).log(Level.SEVERE, null, ex);
                    errorMsg = new String("User settings file error: " + ex.getMessage());
                } catch (SAXException ex) {
                    Logger.getLogger(ProcessXML.class.getName()).log(Level.SEVERE, null, ex);
                    errorMsg = new String("User settings file error: " + ex.getMessage());
                } catch (IOException ex) {
                    Logger.getLogger(ProcessXML.class.getName()).log(Level.SEVERE, null, ex);
                    errorMsg = new String("User settings file error: " + ex.getMessage());
                }
            }
        }
        if (dom != null) {
            Element docEle = dom.getDocumentElement();
            if (docEle != null) {
                nodeList = docEle.getElementsByTagName(nodeType);
            }
        }
        return nodeList;
    }

    private HashMap parseNodes(NodeList nodeList, String nodeType) {

        HashMap nodes = null;

        if (nodeList != null && nodeList.getLength() > 0) {
            nodes = new HashMap();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element el = (Element) nodeList.item(i);
                if (nodeType.equalsIgnoreCase("CredentialInfo")) {
                    AWSCredential awsCredential = getAWSCredential(el);
                    nodes.put(awsCredential.getAwsAccountNickName(), awsCredential);
                } else if (nodeType.equalsIgnoreCase("RegionInfo")) {
                    EC2Region ec2Region = getEC2Region(el);
                    nodes.put(ec2Region.getRegionName(), ec2Region);
                } else if (nodeType.equalsIgnoreCase("S3ServerInfo")) {
                    S3StorageServer s3StorageServer = getS3StorageServer(el);
                    nodes.put(s3StorageServer.getS3ServerName(), s3StorageServer);
                } else if (nodeType.equalsIgnoreCase("SDBServerInfo")) {
                    SDBServer sdbServer = getSDBServer(el);
                    nodes.put(sdbServer.getServer(), sdbServer);
                }
            }
        }
        return nodes;
    }

    private EC2Region getEC2Region(Element regionEl) {

        EC2Region ec2Region = new EC2Region();

        String regionName = getTextValue(regionEl, "regionName");
        String regionUrl = getTextValue(regionEl, "regionUrl");
        String regionDisplayName = getTextValue(regionEl, "regionDisplayName");
        String server = getTextValue(regionEl, "server");
        String serverResourcePrefix = getTextValue(regionEl, "serverResourcePrefix");
        String serverPortStr = getTextValue(regionEl, "serverPort");
        String proxyHost = getTextValue(regionEl, "regionProxyHost");
        String proxyPortStr = getTextValue(regionEl, "regionProxyPort");

        ec2Region.setRegionName(regionName);
        ec2Region.setRegionUrl(regionUrl);
        ec2Region.setServer(server);
        ec2Region.setServerResourcePrefix(serverResourcePrefix);
        ec2Region.setServerPort(serverPortStr);
        ec2Region.setProxyHost(proxyHost);
        ec2Region.setProxyPort(proxyPortStr);

        if (regionDisplayName == null) {
            ec2Region.setRegionDisplayName(regionName);
        } else {
            ec2Region.setRegionDisplayName(regionDisplayName);
        }
        return ec2Region;
    }

    private AWSCredential getAWSCredential(Element awsCredentialEl) {

        AWSCredential awsCredential = new AWSCredential();

        String awsAccountId = getTextValue(awsCredentialEl, "awsAccountId");
        String awsAccessKey = getTextValue(awsCredentialEl, "awsAccessKey");
        String awsSecretKey = getTextValue(awsCredentialEl, "awsSecretKey");
        String awsAccountNickName = getTextValue(awsCredentialEl, "awsAccountNickName");
        String awsSDBdomain = getTextValue(awsCredentialEl, "awsSDBdomain");
        String awsReadAMIs = getTextValue(awsCredentialEl, "awsReadAMIs");
        String sshUser = getTextValue(awsCredentialEl, "sshUser");

        awsCredential.setAwsAccessKey(awsAccessKey);
        awsCredential.setAwsSecretKey(awsSecretKey);
        awsCredential.setAwsAccountId(awsAccountId);

        if (awsAccountNickName == null) {
            awsCredential.setAwsAccountNickName(awsAccountId);
        } else {
            awsCredential.setAwsAccountNickName(awsAccountNickName);
        }

        awsCredential.setAwsSDBdomain(awsSDBdomain);
        awsCredential.setAwsReadAMIs(awsReadAMIs);
        awsCredential.setSshUser(sshUser);

        return awsCredential;
    }

    private S3StorageServer getS3StorageServer(Element s3serverEl) {
        S3StorageServer s3StorageServer = new S3StorageServer();

        String s3ServerName = getTextValue(s3serverEl, "s3ServerName");
        String s3Server = getTextValue(s3serverEl, "s3Server");
        String s3ResourcePrefix = getTextValue(s3serverEl, "s3ResourcePrefix");
        String s3ServerPortStr = getTextValue(s3serverEl, "s3ServerPort");
        String s3HTTPSonlyStr = getTextValue(s3serverEl, "s3HTTPSonly");
        String s3DisableDNSbucketsStr = getTextValue(s3serverEl, "s3DisableDNSbuckets");
        String s3serverProxyHost = getTextValue(s3serverEl, "s3serverProxyHost");
        String s3serverProxyPortStr = getTextValue(s3serverEl, "s3serverProxyPort");

        s3StorageServer.setS3ServerPort(s3ServerPortStr);
        s3StorageServer.setS3Server(s3Server);
        s3StorageServer.setS3ResourcePrefix(s3ResourcePrefix);
        s3StorageServer.setS3DisableDNSbuckets(s3DisableDNSbucketsStr);
        s3StorageServer.setS3HTTPSonly(s3HTTPSonlyStr);
        s3StorageServer.setS3serverProxyHost(s3serverProxyHost);
        s3StorageServer.setS3serverProxyPort(s3serverProxyPortStr);

        if (s3ServerName == null) {
            s3StorageServer.setS3ServerName(s3Server);
        } else {
            s3StorageServer.setS3ServerName(s3ServerName);
        }

        return s3StorageServer;
    }

    private SDBServer getSDBServer(Element serverEl) {

        SDBServer sdbServer = new SDBServer();

        String serverName = getTextValue(serverEl, "serverName");
        String server = getTextValue(serverEl, "server");
        String serverPortStr = getTextValue(serverEl, "serverPort");
        String serverProxyHost = getTextValue(serverEl, "serverProxyHost");
        String serverProxyPortStr = getTextValue(serverEl, "serverProxyPort");

        sdbServer.setServerPort(serverPortStr);
        sdbServer.setServer(server);
        sdbServer.setServerProxyHost(serverProxyHost);
        sdbServer.setServerProxyPort(serverProxyPortStr);

        if (serverName == null) {
            sdbServer.setServerName(server);
        } else {
            sdbServer.setServerName(serverName);
        }

        return sdbServer;
    }

    private String getTextValue(Element ele, String tagName) {
        String textVal = null;
        NodeList nl = ele.getElementsByTagName(tagName);
        if (nl != null && nl.getLength() > 0) {
            Element el = (Element) nl.item(0);
            textVal = el.getFirstChild().getNodeValue().trim();
        }
        return textVal;
    }
}
